import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:kxy_flutter_app/auth.dart';
import 'package:kxy_flutter_app/components/image_view.dart';
import 'package:kxy_flutter_app/components/loading_dialog.dart';
import 'package:kxy_flutter_app/components/loading_widget.dart';
import 'package:kxy_flutter_app/components/video_widget.dart';
import 'package:kxy_flutter_app/helper/http.dart';
import 'package:kxy_flutter_app/model/course.dart';
import 'package:kxy_flutter_app/model/course_resource.dart';
import 'package:kxy_flutter_app/model/exam.dart';
import 'package:kxy_flutter_app/services/integral_service.dart';
import 'package:kxy_flutter_app/view/course/detail/course_detail_header.dart';
import 'package:kxy_flutter_app/view/course/detail/course_detail_resource.dart';
import 'package:kxy_flutter_app/view/course/detail/course_detail_viewer.dart';
import 'package:kxy_flutter_app/view/course/detail/course_timer.dart';
import 'package:kxy_flutter_app/view/examination/do_exam_view.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';

class CourseDetailView extends StatefulWidget {
  final String courseId;

  CourseDetailView({
    Key key,
    @required this.courseId,
  }) : super(key: key);

  @override
  _CourseDetailViewState createState() => _CourseDetailViewState();
}

class _CourseDetailViewState extends State<CourseDetailView> {
  Course course;
  Future loadFuture;
  bool showDetail = false;
  Widget timeWidget;
  CourseResource currentResource;
  LoadingDialog loading;
  Function onPlay;

  @override
  void initState() {
    super.initState();
    loadFuture = loadCourse();
    loading = LoadingDialog(context);
  }

  @override
  void dispose() {
    stopCurrentStudy().then((value) {
      super.dispose();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color.fromRGBO(245, 245, 245, 1),
      appBar: AppBar(title: Text('课程学习')),
      body: body(),
    );
  }

  Widget body() {
    return FutureBuilder(
      future: loadFuture,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          if (course == null) {
            return Center(
              child: Text('课程不存在'),
            );
          }
          return Column(
            children: [
              mediaWidget(),
              Expanded(
                child: ListView(children: [
                  CourseDetailHeader(course: course),
                  CourseDetailViewer(course: course),
                  CourseDetailResource(course: course, startCallback: study),
                ]),
              ),
            ],
          );
        }
        return LoadingWidget();
      },
    );
  }

  Widget mediaWidget() {
    var width = MediaQuery.of(context).size.width;
    var height = width / 16 * 9;
    Widget media;

    if (currentResource == null) {
      media = CachedNetworkImage(
        imageUrl: course.imgUrl,
        fit: BoxFit.cover,
        height: height,
        width: width,
      );
    } else if (currentResource.type == ResourceType.Picture) {
      media = GestureDetector(
        child: CachedNetworkImage(
          imageUrl: currentResource.resourceUrl,
          fit: BoxFit.cover,
          height: height,
          width: width,
        ),
        onTap: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (cxt) => ImageView(url: currentResource.resourceUrl),
            ),
          );
        },
      );
    } else if (currentResource.type == ResourceType.Video) {
      media = VideoWidget(
        url: currentResource.resourceUrl,
        aspectRatio: 16 / 9,
        onPlay: (() {
          if (onPlay != null) onPlay();
        }),
      );
    } else {
      media = GestureDetector(
        child: CachedNetworkImage(
          imageUrl: course.imgUrl,
          fit: BoxFit.cover,
          height: height,
          width: width,
        ),
        onTap: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (cxt) => ImageView(url: currentResource.resourceUrl),
            ),
          );
        },
      );
    }

    return Stack(
      children: [
        media,
        Positioned(
          top: 0,
          right: 0,
          child: timeWidget ?? Container(),
        ),
      ],
    );
  }

  Future study(String resourceId) async {
    await stopCurrentStudy();
    setState(() {
      currentResource = course.resourceList.singleWhere((element) => element.id == resourceId);
      currentResource.learning = true;
    });

    switch (currentResource.type) {
      case ResourceType.Picture:
        setState(() {
          if (currentResource.status != ResourceStatus.Completed) {
            currentResource.status = ResourceStatus.Learning;
            timeWidget = new CourseTimer(
              resource: currentResource,
              complete: stopCurrentStudy,
              finishRate: course.finishRate,
            );
          }
        });
        break;
      case ResourceType.Video:
        onPlay = () => setState(() {
              if (currentResource.status != ResourceStatus.Completed) {
                currentResource.status = ResourceStatus.Learning;
                timeWidget = new CourseTimer(
                  resource: currentResource,
                  complete: stopCurrentStudy,
                  finishRate: course.finishRate,
                );
              }
            });
        break;
      case ResourceType.Document:
        await openFile(currentResource);
        currentResource.learnTime = currentResource.courseTime;
        await stopCurrentStudy();
        break;
      case ResourceType.Exam:
        await gotoExam(currentResource.idInfo, course.id);
        break;
      default:
        setState(() {
          if (currentResource.status != ResourceStatus.Completed) {
            currentResource.status = ResourceStatus.Learning;
            timeWidget = new CourseTimer(
              resource: currentResource,
              complete: stopCurrentStudy,
              finishRate: course.finishRate,
            );
          }
        });
    }
  }

  Future stopCurrentStudy() async {
    if (currentResource == null) return;

    if (currentResource.status == ResourceStatus.Completed) {
      setState(() {
        currentResource.learning = false;
      });
      return;
    }
    if (currentResource.type == ResourceType.Exam) {
      setState(() {
        currentResource.learning = false;
      });
      return;
    }

    if (mounted) {
      setState(() {
        currentResource.learning = false;
        int finishTime = (currentResource.courseTime * course.finishRate / 100).floor();
        if (currentResource.learnTime >= finishTime) {
          currentResource.status = ResourceStatus.Completed;
          IntegralService.addCourseResourceCompleted(currentResource.id, currentResource.type);
        } else {
          currentResource.status = ResourceStatus.Learning;
        }
        timeWidget = null;
      });
    }
    await saveResourceState(currentResource);
    await refreshStatus();
  }

  Future refreshStatus() async {
    var res = await Http.instance.post('/train-app/courseapp/courseStatus', params: {
      'courseId': course.id,
      'userId': Auth.instance.userId,
    });

    if (res.code == 200) {
      var resStatus = CourseStatus.values[res.data];
      if (course.status != resStatus) {
        if (resStatus == CourseStatus.Completed) {
          IntegralService.addCourseCompleted(course.id);
        }
        setState(() {
          course.status = CourseStatus.values[res.data];
        });
      }
    }
  }

  Future saveResourceState(CourseResource resource) async {
    var res = await Http.instance.post('/train-app/courseapp/saveResourceHistory', params: {
      'courseId': course.id,
      'resourceId': resource.id,
      'learnTime': resource.learnTime,
      'status': resource.status.index,
      'type': resource.type.index,
      'userId': Auth.instance.userId,
    });
    if (res.code != 200) {
      Fluttertoast.showToast(msg: res.msg);
    }
  }

  Future gotoExam(String examId, String courseId) async {
    var exam = new Exam(
      id: examId,
      name: '课程考试',
      type: 1,
      courseId: courseId,
    );
    var isPass = await Navigator.of(context).push(
      MaterialPageRoute(
        builder: (cxt) {
          return DoExamView(exam: exam);
        },
      ),
    );

    if (isPass != null) {
      if (isPass) {
        IntegralService.addCourseResourceCompleted(currentResource.id, currentResource.type);
      }
      setState(() {
        currentResource.status = isPass ? ResourceStatus.Completed : ResourceStatus.Learning;
      });
    }
  }

  Future openFile(CourseResource resource) async {
    loading.show(text: '加载文件');
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;

    var temp = resource.resourceUrl.split('/');
    if (temp.length > 0) {
      var name = temp[temp.length - 1];
      var extName = name.substring(name.lastIndexOf('.'), name.length);
      var path = appDocPath + '/' + resource.name + extName;
      File file = new File(path);
      if (!await file.exists()) {
        await Http.instance.download(resource.resourceUrl, path);
      }
      await OpenFile.open(path);
    }
    loading.dismiss();
  }

  Future loadCourse() async {
    var res = await Http.instance.post('/train-app/courseapp/getcourseinfo', params: {
      'courseId': widget.courseId,
      'userId': Auth.instance.userId,
    });

    if (res.code == 200) {
      course = Course.fromJson(res.data);
      course.viewCount++;
    } else {
      Fluttertoast.showToast(msg: res.msg);
    }
  }
}
